
#ifndef _MPOOL_H_
#define _MPOOL_H_

#ifndef QF_MPOOL_SIZ_SIZE
#define QF_MPOOL_SIZ_SIZE 2
#endif
#if (QF_MPOOL_SIZ_SIZE == 1)
typedef uint8_t QMPoolSize;
#elif (QF_MPOOL_SIZ_SIZE == 2)

typedef uint16_t QMPoolSize;
#elif (QF_MPOOL_SIZ_SIZE == 4)
typedef uint32_t QMPoolSize;
#else
#error "QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1, 2, or 4"
#endif

/****************************************************************************/
#ifndef QF_MPOOL_CTR_SIZE
#define QF_MPOOL_CTR_SIZE 2
#endif
#if (QF_MPOOL_CTR_SIZE == 1)
typedef uint8_t QMPoolCtr;
#elif (QF_MPOOL_CTR_SIZE == 2)
typedef uint16_t QMPoolCtr;
#elif (QF_MPOOL_CTR_SIZE == 4)
typedef uint32_t QMPoolCtr;
#else
#error "QF_MPOOL_CTR_SIZE defined incorrectly, expected 1, 2, or 4"
#endif

typedef struct QFreeBlockTag
{
    struct QFreeBlockTag *next;
} QFreeBlock;


typedef struct QMPoolTag
{
    /** The head of the linked list of free blocks
    */
    void *free;

    /** the original start this pool
    */
    void *start;

    /** the last memory block managed by this memory pool
    */
    void *end;

    /**  maximum block size (in bytes)
    */
    QMPoolSize blockSize;

    /** total number of blocks
    */
    QMPoolCtr nTot;

    /** number of free blocks remaining
    */
    QMPoolCtr nFree;

    /** minimum number of free blocks ever present in this pool
    *
    * \note this attribute remembers the low watermark of the pool,
    * which provides a valuable information for sizing event pools.
    * \sa QF_getPoolMargin().
    */
    QMPoolCtr nMin;
} MPool;


void MPool_Init(MPool *me, void *poolSto,
                 uint32_t poolSize, QMPoolSize blockSize);

void *MPool_Get(MPool *me);

void MPool_Put(MPool *me, void *b);


#endif

